#include "userwindow.h"
#include "ui_userwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QCryptographicHash> // md5加密的库
#include <QFile>
#include <QtCharts>
static void loadStyle(const QString &styleName){
    //加载样式表
    QString qss;
    QFile file(styleName);
    if (file.open(QFile::ReadOnly)) {
        //用QTextStream读取样式文件不用区分文件编码 带bom也行
        QStringList list;
        QTextStream in(&file);
        //in.setCodec("utf-8");
        while (!in.atEnd()) {
            QString line;
            in >> line;
            list << line;
        }

        file.close();
        qss = list.join("\n");
        QString paletteColor = qss.mid(20, 7);
        qApp->setPalette(QPalette(paletteColor));
        //用时主要在下面这句
        qApp->setStyleSheet(qss);
    }
}

UserWindow::UserWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::UserWindow)
{
    ui->setupUi(this);
    this->setFixedSize(this->geometry().size());
    db=new DatabaseFunction();
    ui->trainNumInfoTable->setColumnWidth(0,30);
    ui->StationInfoTable->setColumnWidth(0,30);
    ui->buyTable->setColumnWidth(7,126);

    timer= new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(onTimeOut()));
    timer->start(500);

    //双击单元格，展示该行所在列车经停站信息
    connect(ui->trainNumInfoTable,SIGNAL(cellDoubleClicked(int,int)),this,SLOT(disPlayTrainInfoByTrainNum(int,int)));
    connect(ui->StationInfoTable,SIGNAL(cellDoubleClicked(int,int)),this,SLOT(disPlayTrainInfoByStation(int,int)));
    //查询到列车经停站信息，将数据传送给子界面
    connect(this,SIGNAL(sendSubStationInfo(QSqlQuery)),subWindow,SLOT(receiveSubInfo(QSqlQuery)));

    //接收要购买的车票所在的列车号码
    connect(this,SIGNAL(sendTrainNum(QString,QString)),buyWindow,SLOT(receiveTrainNum(QString,QString)));
}


UserWindow::~UserWindow()
{
    delete ui;
}

//点击切换界面到首页
void UserWindow::on_mainPageBtn_clicked()
{
    ui->displayWidget->setCurrentWidget(ui->helloPage);
}

//***************个人中心*******************
//点击修改密码，跳转界面
void UserWindow::on_revisePsw_clicked()
{
    ui->displayWidget->setCurrentWidget(ui->revisePswPage);
}




//确认修改密码
void UserWindow::on_confirmRevise_clicked()
{
    QString psw=ui->originPsw->text();
    QString newPsw=ui->newPsw->text();
    QString confirmNewPsw=ui->confirmNewPsw->text();

    //异常判断，查看是否遗漏输入
    if(psw.isEmpty()||newPsw.isEmpty()||confirmNewPsw.isEmpty()){
       QMessageBox::critical(this, "错误", "请输入新旧密码!");
       ui->originPsw->setFocus();
       return;
    }

    //查看两次密码是否匹配
    if(newPsw!=confirmNewPsw){
        QMessageBox::critical(this, "错误", "前后输入密码不一致!");
        ui->newPsw->setFocus();
        return;
    }

    QString pswMd5 =
        QCryptographicHash::hash(psw.toLatin1(), QCryptographicHash::Md5).toHex();

    //查看原密码是否输入正确
    QString sql=QString("select * from user where username='%1' and password='%2'").
            arg(username,pswMd5);

    //创建执行语句对象
    QSqlQuery result(sql);

    //判断该用户是否存在
    if(!result.next()){
       QMessageBox::critical(this, "错误", "原密码不正确!");
       return;
    }

    // 修改用户密码
    // 将密码转换为md5格式
    pswMd5 =
        QCryptographicHash::hash(newPsw.toLatin1(), QCryptographicHash::Md5).toHex();

    sql=QString("update user set password='%1' where username='%2'")
                .arg(pswMd5,username);

    if(result.exec(sql)){
        QMessageBox::information(this, "成功", "密码更新成功!");
    }else{
        QMessageBox::critical(this, "提示", "更改失败！");
    }

}

//接收登陆界面传递来的用户名信息。
void UserWindow::receiveData(QString str)
{
    this->username=str;
    qDebug()<<this->username;
}


// 退出按钮
void UserWindow::on_loguot_clicked()
{
    QApplication* app = nullptr;
    app->exit(0);
}

//***************列车信息查询——按车次查询*******************
//切换到按车次查询页面
void UserWindow::on_trainNum_clicked()
{
    ui->displayWidget->setCurrentWidget(ui->trainNumPage);
}

//根据车次号查询列车信息
void UserWindow::on_trainNumBtn_clicked()
{
    //清空上一次查询到的内容
    int rowNum=ui->trainNumInfoTable->rowCount();
    for(int i=0;i<rowNum;i++){
        ui->trainNumInfoTable->removeRow(0);
    }

    //获取车次号
    QString trainNum=ui->trainNumSearch->text();
    if(trainNum.isEmpty()){
        return;
    }

    //获取查询结果
    QSqlQuery result=db->searchInfoByTrainNum(trainNum);
    int columns=ui->trainNumInfoTable->columnCount();

    for(int i=0;result.next();i++){
        //增加一行
        ui->trainNumInfoTable->insertRow(i);
        ui->trainNumInfoTable->setItem(i,0,new QTableWidgetItem(">"));
        //填充每一列的数值
        for(int j=0;j<columns-1;j++){
            ui->trainNumInfoTable->setItem(i,j+1,new QTableWidgetItem(result.value(j).toString()));
        }
    }
}

//根据当前选取的行号，展示该车次途径站的信息。
void UserWindow::disPlayTrainInfoByTrainNum(int nrow, int ncolum)
{
    Q_UNUSED(ncolum);
    //获取当前选区的行和列
    int curRow=nrow;

    //根据行，确定列车车次，调用接口从数据库中查询途径站信息
    QString trainNum =ui->trainNumInfoTable->item(curRow,1)->text();

    QSqlQuery result=db->searchSubInfoByTrainNum(trainNum);

    emit sendSubStationInfo(result);
    //设置不可操纵父窗口
    subWindow->setWindowModality(Qt::ApplicationModal);
    subWindow->show();
}

//根据当前选取的车站，展示该车次途径站的信息。
void UserWindow::disPlayTrainInfoByStation(int nrow, int ncolum)
{
    Q_UNUSED(ncolum);
    //获取当前选的行和列
    int curRow=nrow;

    //根据行，确定列车车次，调用接口从数据库中查询途径站信息
    QString trainNum =ui->StationInfoTable->item(curRow,1)->text();

    QSqlQuery result=db->searchSubInfoByTrainNum(trainNum);

    emit sendSubStationInfo(result);
    //设置不可操纵父窗口
    subWindow->setWindowModality(Qt::ApplicationModal);
    subWindow->show();
}


//***************列车信息查询——按起始站和终点站查询*******************
//切换到按起始站和终点站查询页面
void UserWindow::on_station2Station_clicked()
{
    ui->displayWidget->setCurrentWidget(ui->station2StationPage);
}

//根据用户输入的起始站和终点站查询对应车票信息
void UserWindow::on_stationSearchBtn_clicked()
{
    //清空上一次查询到的内容
    int rowNum=ui->StationInfoTable->rowCount();
    for(int i=0;i<rowNum;i++){
        ui->StationInfoTable->removeRow(0);
    }

    QString startStation=ui->startStation->text();
    QString endStation=ui->endStation->text();

    //异常检测，若未输入则直接返回
    if(startStation.isEmpty()||endStation.isEmpty()){
        return;
    }

    //获取查询结果
    QSqlQuery result=db->searchInfoByStation(startStation,endStation);
    int columns=ui->StationInfoTable->columnCount();

    for(int i=0;result.next();i++){
        //增加一行
        ui->StationInfoTable->insertRow(i);
        ui->StationInfoTable->setItem(i,0,new QTableWidgetItem(">"));
        //填充每一列的数值
        for(int j=0;j<columns-1;j++){
            ui->StationInfoTable->setItem(i,j+1,new QTableWidgetItem(result.value(j).toString()));
        }
    }
}


//***************车票购买——订单查询*******************
//切换到余票查询界面
void UserWindow::on_leftTickets_clicked()
{
    ui->displayWidget->setCurrentWidget(ui->leftTicketPage);
}

//根据车次查询余票
void UserWindow::on_queryTrainNumBtn_clicked()
{
    //清空上一次查询到的内容
    int rowNum=ui->buyTable->rowCount();
    for(int i=0;i<rowNum;i++){
        ui->buyTable->removeRow(0);
    }

    //获取车次号
    QString trainNum=ui->queryTrainNum->text();
    //异常判断，如果为空，则返回
    if(trainNum.isEmpty()){
        return;
    }

    //调用接口，并接受返回到的查询结果
    QSqlQuery result=db->searchAllInfoByTrainNum(trainNum);
    int columns=ui->buyTable->columnCount();

    //将结果展示在界面
    for(int i=0;result.next();i++){
        //增加一行
        ui->buyTable->insertRow(i);
        //填充每一列的数值
        for(int j=0;j<columns-1;j++){
            ui->buyTable->setItem(i,j,new QTableWidgetItem(result.value(j).toString()));
        }
        QPushButton *btn = new QPushButton();
        btn->setText(tr("购买"));
        connect(btn,SIGNAL(clicked(bool)),this,SLOT(buyBtnSlot()));
        QWidget *tmp_widget = new QWidget();
        QHBoxLayout *tmp_layout = new QHBoxLayout(tmp_widget);
        tmp_layout->addWidget(btn);
        tmp_layout->setMargin(0);

        ui->buyTable->setCellWidget(i,columns-1,tmp_widget);
    }
}
//起始站，终点站查询
void UserWindow::on_queryStationSearchBtn_clicked()
{
    //清空上一次查询到的内容
    int rowNum=ui->buyTable->rowCount();
    for(int i=0;i<rowNum;i++){
        ui->buyTable->removeRow(0);
    }
    //获取车站
    QString start=ui->queryStartStation->text();
    QString end=ui->queryEndStation->text();

    //异常判断，如果为空，则返回
    if(start.isEmpty()||end.isEmpty()){
        return;
    }

    //调用接口，接收返回的查询结果
    QSqlQuery result=db->searchAllInfoByStation(start,end);
    int columns=ui->buyTable->columnCount();

    //将结果展示在界面
    for(int i=0;result.next();i++){
        //增加一行
        ui->buyTable->insertRow(i);
        //填充每一列的数值
        for(int j=0;j<columns-1;j++){
            ui->buyTable->setItem(i,j,new QTableWidgetItem(result.value(j).toString()));
        }

        QPushButton *btn = new QPushButton();
        btn->setText(tr("购买"));
        connect(btn,SIGNAL(clicked(bool)),this,SLOT(buyBtnSlot()));
        ui->buyTable->setCellWidget(i,columns-1,btn);
    }
}

// 退票按钮点击后的相关操作
void UserWindow::returnBtnSlot()
{
    // 获取按钮的指针
    QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
    if(NULL == pushButton_){
            return;
    }
    // 获取按钮的x坐标和y坐标
    int x = pushButton_->parentWidget()->frameGeometry().x();
    int y = pushButton_->parentWidget()->frameGeometry().y();

    // 根据按钮的x和y坐标来定位对应的单元格
    QModelIndex index = ui->alreadyPayTable->indexAt(QPoint(x, y));
    // 获取该按钮所在表格的行号和列号
    int row = index.row();
    qDebug()<<row;
    QString id=ui->alreadyPayTable->item(row,0)->text();
    QString trainNum=ui->alreadyPayTable->item(row,1)->text();
    QString start=ui->alreadyPayTable->item(row,3)->text();
    QString end=ui->alreadyPayTable->item(row,5)->text();
    QString price=db->getPrice(id);
    trainNum=processTrainNum(trainNum);
    db->returnLeftTickets(trainNum,start,end);

    if(db->desIncomeDB(trainNum,price.toInt())&&db->returnOrdering(id)){
        ui->alreadyPayTable->removeRow(row);
    }
}

// 支付按钮点击后的相关操作
void UserWindow::payBtnSlot()
{
    // 获取按钮的指针
    QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
    if(NULL == pushButton_){
            return;
    }
    // 获取按钮的x坐标和y坐标
    int x = pushButton_->parentWidget()->frameGeometry().x();
    int y = pushButton_->parentWidget()->frameGeometry().y();
    // 根据按钮的x和y坐标来定位对应的单元格
    QModelIndex index = ui->unpayTable->indexAt(QPoint(x, y));
    // 获取该按钮所在表格的行号和列号
    int row = index.row();

    QString id=ui->unpayTable->item(row,0)->text();
    QString trainNum=ui->unpayTable->item(row,1)->text();
    QString start=ui->unpayTable->item(row,3)->text();
    QString end=ui->unpayTable->item(row,5)->text();
    QString price=db->getPrice(id);
    trainNum=processTrainNum(trainNum);

    // 这里需要根据列车号，起始站和终点站来获取该区间段的余票数，
    // 如果已经卖完了，则提示购票失败
    if(!db->isTicketsEnough(trainNum,start,end)){
        QMessageBox::critical(this,"错误","余票不足,购票失败!");
        return;
    }
    db->minusLeftTickets(trainNum,start,end);
    if(db->writeIncomeDB(trainNum,price.toInt())&&db->payUnpayOrdering(id)){
        ui->unpayTable->removeRow(row);
    }
}

// 删除按钮点击后的对应操作
void UserWindow::delBtnSlot()
{
    // 获取按钮的指针
    QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
    if(NULL == pushButton_){
            return;
    }
    // 获取按钮的x坐标和y坐标
    int x = pushButton_->parentWidget()->frameGeometry().x();
    int y = pushButton_->parentWidget()->frameGeometry().y();
    // 根据按钮的x和y坐标来定位对应的单元格
    QModelIndex index = ui->unpayTable->indexAt(QPoint(x, y));
    // 获取该按钮所在表格的行号和列号
    int row = index.row();

    QString id=ui->unpayTable->item(row,0)->text();

    if(db->delUnpayOrdering(id)){
        ui->unpayTable->removeRow(row);
    }
}

// 购买按钮点击
void UserWindow::buyBtnSlot()
{
    if(!db->isInfoComplete(username)){
        QMessageBox::critical(this,"错误","请完善个人信息后再购票");
        return;
    }
    // 获取按钮的指针
    QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
    if(NULL == pushButton_){
        return;
    }
    // 获取按钮的x坐标和y坐标
    int x = pushButton_->parentWidget()->frameGeometry().x();
    int y = pushButton_->parentWidget()->frameGeometry().y();

    // 根据按钮的x和y坐标来定位对应的单元格
    QModelIndex index = ui->buyTable->indexAt(QPoint(x, y));
    // 获取该按钮所在表格的行号
    int row = index.row();

    QString trainNum=ui->buyTable->item(row,0)->text();
    trainNum=processTrainNum(trainNum);
    emit sendTrainNum(trainNum,username);

    //设置父界面不可操作
    buyWindow->setWindowModality(Qt::ApplicationModal);
    buyWindow->show();
}


//购票界面
void UserWindow::disPlayBuyWindow(int nrow, int ncolum)
{
    //如果点击的不是购买那个格子，直接返回
    if(ncolum!=7){
        return;
    }
    buyWindow->clearAll();
    emit sendTrainNum(ui->buyTable->item(nrow,0)->text(),username);

    //设置父界面不可操作
    buyWindow->setWindowModality(Qt::ApplicationModal);
    buyWindow->show();
}

//***************订单查询——已支付订单*******************
//切换到已支付订单界面
void UserWindow::on_alreadyPay_clicked()
{
    //清空上一次查询到的内容
    int rowNum=ui->alreadyPayTable->rowCount();
    for(int i=0;i<rowNum;i++){
        ui->alreadyPayTable->removeRow(0);
    }

    //展示出已经支付的订单，并可以实施退票操作
    QSqlQuery result= db->getPayOrdering(username);
    int columns=ui->alreadyPayTable->columnCount();

    //界面初始化
    for(int i=0;result.next();i++){
        //增加一行
        ui->alreadyPayTable->insertRow(i);
        //填充每一列的值
        for(int j=0;j<columns-1;j++){
            ui->alreadyPayTable->setItem(i,j,new QTableWidgetItem(result.value(j).toString()));
        }
        ui->alreadyPayTable->setItem(i,7,new QTableWidgetItem("已支付"));
        QPushButton *btn = new QPushButton();
        btn->setText(tr("退票"));
        connect(btn,SIGNAL(clicked(bool)),this,SLOT(returnBtnSlot()));
        QWidget *tmp_widget = new QWidget();
        QHBoxLayout *tmp_layout = new QHBoxLayout(tmp_widget);
        tmp_layout->addWidget(btn);
        tmp_layout->setMargin(0);

        ui->alreadyPayTable->setCellWidget(i,columns-1,tmp_widget);
    }
    ui->displayWidget->setCurrentWidget(ui->alreadyPayPage);
}

//***************订单查询——未支付订单*******************
//切换到未支付订单界面
void UserWindow::on_unpay_clicked()
{
    //清空上一次查询到的内容
    int rowNum=ui->unpayTable->rowCount();
    for(int i=0;i<rowNum;i++){
        ui->unpayTable->removeRow(0);
    }

    //展示出已经支付的订单，并可以实施退票操作
    QSqlQuery result= db->getUnpayOrdering(username);
    int columns=ui->unpayTable->columnCount();

    //界面初始化
    for(int i=0;result.next();i++){
        //增加一行
        ui->unpayTable->insertRow(i);
        //填充每一列的值
        for(int j=0;j<columns-1;j++){
            ui->unpayTable->setItem(i,j,new QTableWidgetItem(result.value(j).toString()));
        }
        ui->unpayTable->setItem(i,7,new QTableWidgetItem("未支付"));
        QPushButton *btn_1 = new QPushButton();
        btn_1->setText(tr("支付"));
        connect(btn_1,SIGNAL(clicked(bool)),this,SLOT(payBtnSlot()));
        QPushButton *btn_2 = new QPushButton();
        btn_2->setText(tr("删除"));
        connect(btn_2,SIGNAL(clicked(bool)),this,SLOT(delBtnSlot()));

        QWidget *tmp_widget = new QWidget();
        QHBoxLayout *tmp_layout = new QHBoxLayout(tmp_widget);
        tmp_layout->addWidget(btn_1);
        tmp_layout->addWidget(btn_2);
        tmp_layout->setMargin(0);
        ui->unpayTable->setCellWidget(i,columns-1,tmp_widget);
    }
    ui->displayWidget->setCurrentWidget(ui->unpayPage);
}

// 查看个人信息按钮点击
void UserWindow::on_viewPersonalInfo_clicked()
{
    initPersonalInfo();
    ui->displayWidget->setCurrentWidget(ui->personalDetailPage);
}


// 个人信息修改
void UserWindow::on_reviseBtn_clicked()
{
    // 设置为可修改状态
    isEdit=true;
    ui->usernameLineEdit->setReadOnly(false);
    ui->phoneLineEdit->setReadOnly(false);
    ui->nameLineEdit->setReadOnly(false);
    ui->idCardLineEdit->setReadOnly(false);

}


// 保存用户修改后的个人信息
void UserWindow::on_saveBtn_clicked()
{
    // 若不是可编辑状态，无反应
    if(!isEdit){
        return;
    }

    // 若是可编辑状态，将数据库更新为当前信息
    QString username=ui->usernameLineEdit->text();
    QString phoneNum=ui->phoneLineEdit->text();
    QString name=ui->nameLineEdit->text();
    QString idCard=ui->idCardLineEdit->text();
    QString sex=ui->male->isChecked()?"1":"0";

    // 如果修改后关键信息存在空值，则不允许修改
    if(username==""||phoneNum==""||name==""||idCard==""){
        QMessageBox::critical(this,"错误","个人信息不允许为空");
        return;
    }

    // 进行数据库的修改
    if(!db->updatePersonalInfo(username,phoneNum,name,idCard,sex)){
        QMessageBox::critical(this,"错误","存在非法信息！");
        initPersonalInfo();
    }
    isEdit=false;
    ui->usernameLineEdit->setReadOnly(true);
    ui->phoneLineEdit->setReadOnly(true);
    ui->nameLineEdit->setReadOnly(true);
    ui->idCardLineEdit->setReadOnly(true);
}


// 当男女选项发生变化时
void UserWindow::on_male_stateChanged(int arg1)
{
    Q_UNUSED(arg1);
    if(ui->male->isChecked()){
        ui->female->setCheckState(Qt::Unchecked);
    }else{
        ui->female->setCheckState(Qt::Checked);
    }
}


void UserWindow::on_female_stateChanged(int arg1)
{
    Q_UNUSED(arg1);
    if(ui->female->isChecked()){
        ui->male->setCheckState(Qt::Unchecked);
    }else{
        ui->male->setCheckState(Qt::Checked);
    }
}

// 初始化查看用户信息界面
void UserWindow::initPersonalInfo()
{
    // 从数据库获取用户信息
    QSqlQuery result=db->getPersonalInfo(username);
    // 逐个赋值
    if(result.next()){
        ui->usernameLineEdit->setText(result.value(0).toString());
        ui->phoneLineEdit->setText(result.value(1).toString());
        if(result.value(2).toInt()==0){
            ui->female->setCheckState(Qt::Checked);
        }else{
            ui->male->setCheckState(Qt::Checked);
        }
        ui->nameLineEdit->setText(result.value(3).toString());
        ui->idCardLineEdit->setText(result.value(4).toString());
    }
}




void UserWindow::on_qssCheckBox_stateChanged(int arg1)
{
    if(arg1==0){
        loadStyle(":/qss/lightblue.css");
    }else{
        loadStyle(":/qss/blacksoft.css");
    }
}

// 控制首页label移动
void UserWindow::onTimeOut()
{
    xPos+=10;
    ui->qqLabel->move(30+xPos%651,90);
    if(xPos==650){
        xPos=0;
    }
}

// 将火车编号的子编号删去，返回父编号
QString UserWindow::processTrainNum(QString trainNum)
{
    QString temp="-";
    int index=trainNum.indexOf(temp);
    if(index>0){
        return trainNum.mid(0,index);
    }else{
        return trainNum;
    }
}

// 切换到营业额展示界面
void UserWindow::on_profitBtn_clicked()
{
    // 首先填充界面信息
    createCharts();


    // 然后进行展示

    // 最后界面切换
    ui->displayWidget->setCurrentWidget(ui->profitPage);

}

// 显示营业额柱状图
void UserWindow::createCharts()
{
    QSqlQuery result=db->getTrainAndIncome();
    QBarSeries *series = new QBarSeries();
    QBarSet *set = new QBarSet("营销额");
    QStringList categories;

    while (result.next()) {
        *set<<result.value(1).toInt();
        categories<<result.value(0).toString();
        set->setColor(QColor(qrand()%255, qrand()%255, qrand()%255, 128));
        series->append(set);
    }

    series->setLabelsPosition(QAbstractBarSeries::LabelsPosition::LabelsCenter);
    series->setLabelsVisible(true);

    QChart *chart=new QChart();
    chart->addSeries(series);
    chart->setTitle("列车营销额");
    chart->setAnimationOptions(QChart::SeriesAnimations);


    QBarCategoryAxis *axis=new QBarCategoryAxis();
    axis->append(categories);
    chart->createDefaultAxes();// 创建默认的左侧坐标轴（根据QBarSet设置的值）

    chart->setAxisX(axis,series);

    QValueAxis *axisy=new QValueAxis;
    axisy->setTitleText(tr("单位:元"));

    chart->setAxisY(axisy,series);


    chart->legend()->setVisible(true);//设置图例为显示状态
    chart->legend()->setAlignment(Qt::AlignBottom);// 设置图例的显示位置在底部
    //chart->setTitleFont(QFont("微软雅黑"));

    QChartView *chartView=new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    QGridLayout *myLayout =new QGridLayout();

    if(ui->profitPage->layout()!=NULL){
        delete ui->profitPage->layout();
    }

    myLayout->addWidget(chartView);
    ui->profitPage->setLayout(myLayout);
}

